// 命令模式
// 思想：有时候需要向某些对象发送请求，但是并不知道请求的接收者是谁，也不知道被请求的操作是什么。消除发送者和接收者之间的耦合关系
/*
客户创建命令；调用者执行该命令；接收者在命令执行时执行相应操作
简单命令对象一般用来消除二个对象（调用者和接收者）之间的耦合，而复杂的命令对象则一般用来封装不可分的或事务性的指令。

命令模式的主要用途是把调用对象（用户界面、API和代理等）与实现操作的对象隔离开。凡是两个对象间互动方式需要有更高的模块化程度时都可以用到这种模式

类似与 人-遥控器-电视机
*/

// 命令发起者
function CreateCommand(receiver){
  this.receiver = receiver
}
CreateCommand.prototype.execute = function(){
  this.receiver.action()
}

// 命令接收者
function Receiver1(){
  this.action = function(){
    console.log('执行了接收者1动作')
  }
}
function Receiver2(){
  this.action = function(){
    console.log('执行了接收者2动作')
  }
}

// 命令调度者
function Invoker(receiver1, receiver2){
  this.receiver1 = receiver1
  this.receiver2 = receiver2
}
Invoker.prototype.start1 = function(){
  this.receiver1.execute()
}
Invoker.prototype.start2 = function(){
  this.receiver2.execute()
}

const command1 = new CreateCommand(new Receiver1())
const command2 = new CreateCommand(new Receiver2())

const invoker = new Invoker(command1, command2)
invoker.start1()
invoker.start2()

// 宏命令
const MacroCommand = function(){
  return {
    commandList:[],
    add(command){
      this.commandList.push(command)
    },
    execute(){
      this.commandList.forEach(command => command.execute())
    }
  }
}
const macroCommand = MacroCommand()
macroCommand.add(command1)
macroCommand.add(command2)
macroCommand.execute()


